package de.saarland.uni.lego3d.server.gui.components;

import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.media.j3d.BranchGroup;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

import sun.awt.OrientableFlowLayout;

import com.sun.j3d.utils.scenegraph.io.SceneGraphFileReader;
import com.sun.j3d.utils.scenegraph.io.SceneGraphFileWriter;
import com.sun.j3d.utils.scenegraph.io.UnsupportedUniverseException;

import de.saarland.uni.lego3d.server.gui.MainGUI;

public class HistoryPanel extends JPanel {
	
	MainGUI mGui;
	
	public HistoryPanel(MainGUI mGui) {
		this.mGui = mGui;
		setPreferredSize(new Dimension(100, 650));

		OrientableFlowLayout layout = new OrientableFlowLayout(OrientableFlowLayout.TOP);
		
		layout.setHgap(0);
		layout.setVgap(0);
		
		setLayout(layout);
	}
	
	public void addAndSaveModel(BranchGroup root, BufferedImage img) {
		JLabel label = new JLabel(new ImageIcon(img.getScaledInstance(100, 100, Image.SCALE_SMOOTH)));
		SavedModel savedModel = new SavedModel(root, img);
		savedModel.add(label, BorderLayout.CENTER);
		this.add(savedModel);
		this.revalidate();
	}
	
	private class SavedModel extends JPanel {
		private SavedReadTimer rt;
		String path = null;
		
		public SavedModel(final BranchGroup bg_, BufferedImage img) {
			setPreferredSize(new Dimension(100, 100));
			setLayout(new BorderLayout());
			
			//Duplicate branchgroup
			try {
				path = System.getProperty("user.dir") + File.separator + "ModelL3D_" + (System.currentTimeMillis()) + ".tmp3d";
				
				File f = new File(path);
				
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				ImageIO.write(img, "jpg", baos);
				byte[] bytesOut = baos.toByteArray();
				
				SceneGraphFileWriter fw = new SceneGraphFileWriter(f, mGui.getUniverse(), true, "blaaa", bytesOut);
				fw.writeBranchGraph(bg_);
				fw.close();
				
			} catch (IOException e1) {
				e1.printStackTrace();
			} catch (UnsupportedUniverseException e1) {
				e1.printStackTrace();
			}
			
			this.addMouseListener(new MouseListener() {
				@Override
				public void mouseReleased(MouseEvent arg0) {
					// TODO Auto-generated method stub
				}
				@Override
				public void mousePressed(MouseEvent arg0) {
					// TODO Auto-generated method stub
				}
				@Override
				public void mouseExited(MouseEvent e) {
					if (rt != null) {
						rt.interrupt();
					}
				}
				@Override
				public void mouseEntered(MouseEvent e) {
					rt = new SavedReadTimer(path);
					rt.start();
				}
				@Override
				public void mouseClicked(MouseEvent arg0) {
					// TODO Auto-generated method stub
				}
			});
		}
	}
	
	private class SavedReadTimer extends Thread {
		private int time = 5;
		
		private String path;

		private final int WAIT_TIME = 500;
		
		Cursor c1 = getToolkit().createCustomCursor(new ImageIcon( this.getClass().getResource("/de/saarland/uni/lego3d/textures/loadc_1.png")).getImage(), new Point(10,10), "Cursor" );
		Cursor c2 = getToolkit().createCustomCursor(new ImageIcon( this.getClass().getResource("/de/saarland/uni/lego3d/textures/loadc_2.png")).getImage(), new Point(10,10), "Cursor" );
		Cursor c3 = getToolkit().createCustomCursor(new ImageIcon( this.getClass().getResource("/de/saarland/uni/lego3d/textures/loadc_3.png")).getImage(), new Point(10,10), "Cursor" );
		Cursor c4 = getToolkit().createCustomCursor(new ImageIcon( this.getClass().getResource("/de/saarland/uni/lego3d/textures/loadc_4.png")).getImage(), new Point(10,10), "Cursor" );
		Cursor c5 = getToolkit().createCustomCursor(new ImageIcon( this.getClass().getResource("/de/saarland/uni/lego3d/textures/loadc_5.png")).getImage(), new Point(10,10), "Cursor" );
		
		public SavedReadTimer(String path) {
			this.path = path;
		}
		
		@Override
		public void run() {
			while (!isInterrupted() && time >= 0) {
				if (time == 5) {
					HistoryPanel.this.setCursor(c5);
				} else if (time == 4) {
					HistoryPanel.this.setCursor(c4);
				} else if (time == 3) {
					HistoryPanel.this.setCursor(c3);
				} else if (time == 2) {
					HistoryPanel.this.setCursor(c2);
				} else if (time == 1) {
					HistoryPanel.this.setCursor(c1);
				} else if (time == 0) {
					HistoryPanel.this.setCursor(Cursor.getDefaultCursor());
					
					try {
						SceneGraphFileReader sr = new SceneGraphFileReader(new File(path));
						BranchGroup bg = sr.readBranchGraph(0)[0];
						mGui.initRootBranchGroup(bg);
						sr.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
					
					interrupt();
					continue;
				}
				try {
					time--;
					sleep(WAIT_TIME);
				} catch (InterruptedException e) {
					interrupt();
				}
			}
		}
	}
}
